home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / pmnos.c < prev    next >
Text File  |  1993-09-08  |  42KB  |  1,456 lines

  1. /*
  2.     PMNOS.c - (c) 1992, 1993 Walt Corey KZ1F.
  3. */
  4.  
  5. #define INCL_WIN
  6. #define INCL_WINDDE
  7. #define INCL_WINSTDFONT
  8. #define INCL_DOS
  9. #define INCL_PMSHL
  10. #define INCL_DOSDEVICES
  11. #define INCL_DOSFILEMGR
  12. #define INCL_DEV
  13. #define INCL_GPI
  14. #define INCL_GPILCIDS
  15. #define INCL_DOSNLS
  16. #include <os2.h>
  17. #include <process.h>
  18. #include <time.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stddef.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include "pmnos.h"
  26. #include "pmnosdlg.h"
  27. #include <stdlib.h>
  28. #include "global.h"
  29. #include "cmdparse.h"
  30. #include "config.h"
  31. #include "mbuf.h"
  32. #include "proc.h"
  33. #include "timer.h"
  34. #include "socket.h"
  35. #include "daemon.h"
  36. #include "hardware.h"
  37. #include "tty.h"
  38. #include "usock.h"
  39. #define UM_CMD WM_USER
  40. #define UM_SESSION WM_USER + 1
  41. #define UM_MAIL WM_USER + 10
  42. #define UM_BMAIL WM_USER + 11
  43. #define UM_REFRESH WM_USER + 12
  44. #define UM_LINK WM_USER + 13
  45. #define UM_MLE WM_USER + 14
  46. #define UM_TRACE WM_USER + 15
  47. #define UM_SETCURSOR WM_USER + 16
  48. #define UM_SETFONT WM_USER + 17
  49. #define UM_INSERT WM_USER + 20
  50. #define UM_SETFOCUS WM_USER + 21
  51. #define UM_SETSIZE WM_USER + 23
  52. #define UM_ERROR WM_USER + 107
  53. PFNWP pfnMle;
  54. PFNWP pfnEntry;
  55. typedef struct _pnode {
  56.     HWND    hwndClient;
  57.     PSZ    pszItem;
  58. } NODE, *PNODE;
  59. PNODE    pNode1;
  60. #define KBSIZE 256
  61. extern struct cmds Cmds[],Startcmds[],Stopcmds[],Attab[];
  62. CONVCONTEXT convContext;
  63. extern int Mprunning;
  64. static struct {
  65.     char buf[KBSIZE];
  66.     char *wp;
  67.     char *rp;
  68.     int cnt;
  69.     UCHAR uchScanCode;
  70. } Keyboard;
  71.  
  72. typedef struct
  73.     {
  74.     long    cxClient;
  75.     long    cyClient;
  76.     HWND    hwndMle;
  77.     HWND    hwndEntry;
  78.     struct session *pSession;
  79.     struct proc *display;
  80.     } OBJECT, *POBJECT;
  81. #define ID_TIMER 1
  82.  
  83. #define UM_DRAWLIST WM_USER + 2
  84. #define UM_SIZE_MAIL WM_USER + 3
  85. #define UM_DRAW_MAIL WM_USER + 4
  86. #define UM_SET WM_USER + 5
  87. #define UM_DESTROY WM_USER + 6
  88. #define UM_BS WM_USER + 7
  89. #define UM_ERASELINE WM_USER + 8
  90. #define BUTTON_HEIGHT    26
  91. #define BUTTON_WIDTH    60
  92. #define THREADSTACKSIZE   4096
  93. static VOID setupPrinter(BOOL fSetup);
  94. static void display(int i, void *v1, void *v2);
  95. void newTrace(struct session *sp);
  96. void freeTrace(struct session *sp);
  97. void MailNotify(char *pszUser);
  98. int nosmain(int argc, char **argv);
  99. int kbread(void);
  100. static int kbchar(void);
  101. extern int main_exit;
  102. extern struct proc Cmdpp;
  103. int lMleStyle;
  104. long lScrollWidth;
  105. PDDESTRUCT MakeDDEObject(PSZ pszItemName, USHORT usStatus, USHORT usFormat,
  106.             PVOID pData, USHORT usDataLen);
  107.  
  108. HWND  hwndClient,
  109.       hwndCmd,
  110.       hwndFrame,
  111.       hwndMainFrame,
  112.       hwndList,
  113.       hwndFind,
  114.       hwndLstV,
  115.       hwndMail,
  116.       hwndMenu;
  117. static char Prompt[] = "net> ";
  118. static    BOOL    fHaveFont = FALSE;
  119. HMQ    hmq;
  120. HAB   hab, hab1 ;
  121. HINI    NosIni;
  122. int rc;
  123. FATTRS    fat;
  124. long lcid;
  125. PDRIVDATA   pDriver;
  126. PSZ    pszDriver;
  127. PSZ    pszLogAddr;
  128. USHORT    cxClient, cyClient;
  129. ULONG    usArgc;
  130. CHAR    **pachArgv;
  131. CHAR    szClientClass [] = "PM NOS";
  132. BOOL    fChanged;
  133. ERRORID errid;
  134. RECTL    rectl;
  135. int prtError(HAB hab, HWND hwnd);
  136. unsigned fs;
  137. SWP swp;
  138. MRESULT EXPENTRY AboutDlgProc(HWND hDlg, ULONG msg, MPARAM mp1, MPARAM mp2);
  139. MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  140. MRESULT EXPENTRY Dde1WndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  141. MRESULT EXPENTRY DdeWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  142. MRESULT EXPENTRY NewMleWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  143. MRESULT EXPENTRY NewEntryWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  144. static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU    | FCF_SIZEBORDER |
  145.                 FCF_MINMAX     | FCF_TASKLIST | FCF_MENU |
  146.                 FCF_ICON     | FCF_ACCELTABLE | FCF_SHELLPOSITION ;
  147. int  main (int argc, char **argv);
  148. int  main (int argc, char **argv)
  149. {
  150. QMSG    qmsg;
  151. APIRET  rc;
  152. PSZ pszIniPath;
  153. unsigned long ulSize;
  154.     usArgc = argc;
  155.     pachArgv = argv;
  156.     lMleStyle = WS_VISIBLE;
  157.     convContext.cb = sizeof(CONVCONTEXT);
  158.     hab = WinInitialize (0) ;
  159.     hmq = WinCreateMsgQueue (hab, 50) ;
  160.     NosIni = (HINI)NULL;
  161.     WinRegisterClass(hab, "DDE", DdeWndProc, 0L, sizeof(int *));
  162.     WinRegisterClass(hab, "DDE1", Dde1WndProc, 0L, sizeof(int *));
  163.     WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, sizeof(int *)) ;
  164.     Keyboard.rp = Keyboard.wp = Keyboard.buf;
  165.     lScrollWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
  166.     pszIniPath = malloc(sizeof(FILESTATUS3));
  167.     rc = DosQueryPathInfo("\\spool\\nos.ini", FIL_STANDARD, pszIniPath, sizeof(FILESTATUS3));
  168.     fs = SWP_SHOW | SWP_SIZE |SWP_MOVE;
  169.     if (rc == 0)    /* ini found */
  170.         {
  171.         NosIni = PrfOpenProfile(hab, "\\spool\\nos.ini");
  172.         ulSize = sizeof(RECTL);
  173.         PrfQueryProfileData(NosIni, "NOS", "State", &rectl, &ulSize);
  174.         ulSize = sizeof(FATTRS);
  175.         PrfQueryProfileData(NosIni, "NOS", "Fattr", &fat,  &ulSize);
  176.         ulSize = sizeof(SWP);
  177.         PrfQueryProfileData(NosIni, "NOS", "SWP", &swp,  &ulSize);
  178.         PrfCloseProfile(NosIni);
  179.         fHaveFont = TRUE;
  180.         }
  181.     nosmain(argc, argv);
  182.     hwndMainFrame = hwndFrame;
  183.     flFrameFlags = FCF_TITLEBAR     | FCF_SIZEBORDER |
  184.                 FCF_MINMAX     | FCF_TASKLIST | 
  185.                 FCF_ICON     | FCF_SHELLPOSITION | FCF_ACCELTABLE  ;
  186.  
  187.     hwndMenu = WinWindowFromID(hwndMainFrame, FID_MENU);
  188.     if (NosIni == (HINI)NULL)
  189.         {
  190.         rectl.xLeft = 0L;
  191.         rectl.yBottom = 0L;
  192.         rectl.xRight = fat.lAveCharWidth * 81L + lScrollWidth;
  193.         rectl.yTop = fat.lMaxBaselineExt * 25L;
  194.         WinCalcFrameRect(hwndFrame, &rectl, FALSE);
  195.         }
  196.     else
  197.         {
  198.         rectl.xLeft = swp.x;
  199.         rectl.yBottom = swp.y;
  200.         rectl.xRight = swp.cx;
  201.         rectl.yTop = swp.cy;
  202.         }
  203.     WinPostMsg(hwndCmd, UM_SETSIZE, 0L, 0L);
  204.     Mprunning = TRUE;
  205.     while (WinGetMsg (hab, &qmsg, (HWND)NULL, 0L, 0L))
  206.         WinDispatchMsg (hab, &qmsg);
  207.     WinQueryWindowPos(hwndFrame, &swp);
  208.     NosIni = PrfOpenProfile(hab, "\\spool\\nos.ini");
  209.     PrfWriteProfileData(NosIni, "NOS", "State", &rectl, sizeof(RECTL));
  210.     PrfWriteProfileData(NosIni, "NOS", "Fattr", &fat, sizeof(FATTRS));
  211.     PrfWriteProfileData(NosIni, "NOS", "SWP", &swp, sizeof(SWP));
  212.     PrfCloseProfile(NosIni);
  213.     WinDestroyWindow (hwndFrame);
  214.     WinDestroyMsgQueue (hmq);
  215.     WinTerminate (hab);
  216.     return 0;
  217. }
  218.  
  219. MRESULT EXPENTRY DdeWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  220. {
  221. ULONG    dwTime;
  222. PDDESTRUCT    pddes;
  223. QMSG    qmsg;
  224. PNODE pNode;
  225. PCREATESTRUCT pCreate;
  226.     switch (msg)
  227.         {
  228.         case UM_MAIL:
  229.             pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  230.             if (pNode && pNode->pszItem && (strcmp(pNode->pszItem, PVOIDFROMMP(mp1)) == 0))
  231.                 {
  232.                 pddes = MakeDDEObject(pNode->pszItem,
  233.                                             DDE_FNODATA,
  234.                                             DDEFMT_TEXT,
  235.                                             NULL,
  236.                                             0);
  237.                 WinDdePostMsg(pNode->hwndClient, hwnd, WM_DDE_DATA, pddes, DDEPM_RETRY);
  238.                 }
  239.             break;
  240.  
  241.         case WM_CREATE:
  242.             if (!WinIsWindow(hab, pNode1->hwndClient))
  243.                 return((MRESULT)TRUE);
  244.             WinSetWindowULong(hwnd, 0, (ULONG)pNode1);
  245.             WinDdeRespond(pNode1->hwndClient, hwnd, "PMNOS", "MAIL", &convContext);
  246.             if (pNode1->pszItem)
  247.                 free(pNode->pszItem);
  248.             break;
  249.  
  250.         case WM_DESTROY:
  251.             pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  252.             if (pNode->hwndClient)
  253.                 {
  254.                 WinDdePostMsg(pNode->hwndClient, hwnd, WM_DDE_TERMINATE, 0L, DDEPM_RETRY);
  255.                 dwTime = WinGetCurrentTime (hab) ;
  256.                 while (WinGetCurrentTime (hab) - dwTime < 3000)
  257.                     if (WinPeekMsg (hab, &qmsg, hwnd, WM_DDE_TERMINATE,
  258.                              WM_DDE_TERMINATE, PM_REMOVE))
  259.                     break ;
  260.                 }
  261.             if (pNode->pszItem)
  262.                 free(pNode->pszItem);
  263.             free(pNode);
  264.             break;
  265.  
  266.         case WM_DDE_ADVISE:
  267.             pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  268.             pddes = PVOIDFROMMP(mp2);
  269.             if (pNode->pszItem)
  270.                 free(pNode->pszItem);
  271.             pNode->pszItem = strdup(DDES_PSZITEMNAME((PDDESTRUCT)mp2));
  272.             DosFreeMem(PVOIDFROMMP(mp2));
  273.             break;
  274.  
  275.         case WM_DDE_UNADVISE:
  276.             pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  277.             pddes = PVOIDFROMMP(mp2);
  278.             if (pNode->pszItem)
  279.                 free(pNode->pszItem);
  280.             pNode->pszItem = NULL;
  281.             DosFreeMem(PVOIDFROMMP(mp2));
  282.             break;
  283.  
  284.         case WM_DDE_TERMINATE:
  285.             pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  286.             if (pNode->hwndClient)
  287.                 WinDdePostMsg(pNode->hwndClient, hwnd, WM_DDE_TERMINATE, 0L, DDEPM_RETRY);
  288.             pNode->hwndClient = (HWND)NULL;
  289.             WinDestroyWindow(hwnd);
  290.             break;
  291.  
  292.         default:
  293.             return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  294.         }
  295.     return((MRESULT)NULL);
  296. }
  297.  
  298. MRESULT EXPENTRY Dde1WndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  299. {
  300. PNODE    pNode;
  301. ULONG    dwTime;
  302. PDDESTRUCT    pddes;
  303. QMSG    qmsg;
  304.     pNode = (PNODE)WinQueryWindowULong(hwnd, 0);
  305.     switch (msg)
  306.         {
  307.         case WM_CREATE:
  308.             pNode = (PNODE)PVOIDFROMMP(mp1);
  309.             WinSetWindowULong(hwnd, 0, (ULONG)pNode);
  310.             free(pNode->pszItem);
  311.             break;
  312.  
  313.         case WM_DESTROY:
  314.             if (pNode->hwndClient)
  315.                 {
  316.                 WinDdePostMsg(pNode->hwndClient, hwnd, WM_DDE_TERMINATE, 0L, DDEPM_RETRY);
  317.                 dwTime = WinGetCurrentTime (hab) ;
  318.                 while (WinGetCurrentTime (hab) - dwTime < 3000)
  319.                     if (WinPeekMsg (hab, &qmsg, hwnd, WM_DDE_TERMINATE,
  320.                              WM_DDE_TERMINATE, PM_REMOVE))
  321.                         break ;
  322.                 }
  323.             if (pNode->pszItem)
  324.                 free(pNode->pszItem);
  325.             free(pNode);
  326.             break;
  327.  
  328.         case WM_DDE_ADVISE:
  329.             pddes = PVOIDFROMMP(mp2);
  330.             if (pNode->pszItem)
  331.                 free(pNode->pszItem);
  332.             pNode->pszItem = strdup(DDES_PSZITEMNAME((PDDESTRUCT)mp2));
  333.             DosFreeMem(PVOIDFROMMP(mp2));
  334.             break;
  335.  
  336.         case WM_DDE_UNADVISE:
  337.             pddes = PVOIDFROMMP(mp2);
  338.             if (pNode->pszItem)
  339.                 free(pNode->pszItem);
  340.             pNode->pszItem = NULL;
  341.             DosFreeMem(PVOIDFROMMP(mp2));
  342.             break;
  343.  
  344.         case WM_DDE_TERMINATE:
  345.             if (pNode->hwndClient)
  346.                 WinDdePostMsg(pNode->hwndClient, hwnd, WM_DDE_TERMINATE, 0L, DDEPM_RETRY);
  347.             pNode->hwndClient = (HWND)NULL;
  348.             WinDestroyWindow(hwnd);
  349.             break;
  350.  
  351.         default:
  352.             return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  353.         }
  354.     return((MRESULT)NULL);
  355. }
  356.  
  357.  
  358.  
  359. MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  360. {
  361. ULONG    rc, usInfo, usResult;
  362. PSZ    pszName;
  363. MRESULT mrResult;
  364. PDDEINIT    pddeInit;
  365. HPS    hps;
  366. PFONTMETRICS pFontMetrics;
  367. LONG    cfm, nFonts, lHorzRes, lVertRes;
  368. USHORT    i;
  369. BOOL    fFontNotFound, f8PtNotFound;
  370. HDC    hdcTmp;
  371. POWNERITEM poi;
  372. BOOL fErr;
  373. LONG lErr;
  374. PSZ pszText;
  375. POBJECT        pObject;
  376. struct mbuf *bp;
  377. struct session *sp;
  378. ULONG    ulPostCt, ulCharCnt, cy;
  379. ERRORID err;
  380. PERRINFO pErr;
  381. SWP swp;
  382. PFONTDLG pFont;
  383. PSZ pFamily;
  384. HWND hDlg;
  385. EXCEPTIONREPORTRECORD *pException;
  386. struct proc *tmpProc;
  387.     switch (msg)
  388.     {
  389.     case WM_CREATE:
  390.         pObject = malloc(sizeof(OBJECT));
  391.         memset(pObject, '\0', sizeof(OBJECT));
  392.         WinSetWindowULong(hwnd, 0, (ULONG)pObject);
  393.         if (!fHaveFont)
  394.             {
  395.             /*
  396.             Create special font
  397.             */
  398.             hps = WinGetPS(hwnd);
  399.             hdcTmp = GpiQueryDevice(hps);
  400.             DevQueryCaps(hdcTmp,
  401.                  CAPS_HORIZONTAL_FONT_RES,
  402.                  1L,
  403.                  (PLONG)&lHorzRes);
  404.             DevQueryCaps(hdcTmp,
  405.                  CAPS_VERTICAL_FONT_RES,
  406.                  1L,
  407.                  (PLONG)&lVertRes);
  408.             cfm = 0L;
  409.             nFonts = GpiQueryFonts(hps,
  410.                        QF_PUBLIC,
  411.                        "Courier",
  412.                        &cfm,
  413.                        0L,
  414.                        NULL);
  415.             pFontMetrics = malloc(nFonts * sizeof(FONTMETRICS));
  416.             GpiQueryFonts(hps,
  417.                   QF_PUBLIC,
  418.                   "Courier",
  419.                   &nFonts,
  420.                   (LONG)sizeof(FONTMETRICS),
  421.                   pFontMetrics);
  422.             fFontNotFound = f8PtNotFound = TRUE;
  423.             for (i = 0; (i < (USHORT)nFonts) && fFontNotFound; i++)
  424.                 {
  425.                 /* We are looking for a fixed font type */
  426.                 if ((pFontMetrics[i].fsType & FM_TYPE_FIXED) == 0)
  427.                     continue;
  428.  
  429.                 /* We are further looking for a non-vectored font */
  430.  
  431.                 if ((pFontMetrics[i].fsDefn & FM_DEFN_OUTLINE))
  432.                     continue;
  433.  
  434.                 /* We are further looking for an appropriate resolution */
  435.  
  436.                 if ((pFontMetrics[i].sXDeviceRes != (SHORT)lHorzRes) ||
  437.                 (pFontMetrics[i].sYDeviceRes != (SHORT)lVertRes))
  438.                     continue;
  439.  
  440.                 fFontNotFound = FALSE;
  441.                 }
  442.             i--;
  443.             /* set up for using it */
  444.             memset((char *)&fat, '\0', sizeof(FATTRS));
  445.             fat.usRecordLength = sizeof(fat);
  446.             strcpy((char *)fat.szFacename, (char *)"Courier" );
  447.             if (!fFontNotFound)
  448.                 {
  449.                 fat.fsSelection = pFontMetrics[i].fsSelection;
  450.                 fat.lMatch = pFontMetrics[i].lMatch;
  451.                 strcpy((char *)fat.szFacename, (char *)pFontMetrics[i].szFacename );
  452.                 fat.idRegistry = pFontMetrics[i].idRegistry;
  453.                 fat.usCodePage = (USHORT)GpiQueryCp(hps);
  454.                 fat.lMaxBaselineExt = pFontMetrics[i].lMaxBaselineExt;
  455.                 fat.lAveCharWidth = pFontMetrics[i].lAveCharWidth;
  456.                 }
  457.             if (rc != 2)
  458.                 prtError(hab, hwnd);
  459.             WinReleasePS(hps);
  460.             free((char *)pFontMetrics);
  461.             }
  462.         fHaveFont = TRUE;
  463.         break;
  464.  
  465.     case WM_SAVEAPPLICATION:
  466.         WinQueryWindowPos(hwndMainFrame, &swp);
  467.         NosIni = PrfOpenProfile(hab, "\\spool\\nos.ini");
  468.         PrfWriteProfileData(NosIni, "NOS", "State", &rectl, sizeof(RECTL));
  469.         PrfWriteProfileData(NosIni, "NOS", "Fattr", &fat, sizeof(FATTRS));
  470.         PrfWriteProfileData(NosIni, "NOS", "SWP", &swp, sizeof(SWP));
  471.         PrfCloseProfile(NosIni);
  472.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  473.         break;
  474.  
  475.     case UM_SETSIZE:
  476.         WinSetWindowPos(hwndFrame,
  477.                         HWND_TOP,
  478.                         rectl.xLeft,
  479.                         rectl.yBottom,
  480.                         rectl.xRight,
  481.                         rectl.yTop,
  482.                         NosIni ? fs : (SWP_SHOW | SWP_SIZE));
  483.         break;
  484.  
  485.     case UM_LINK:
  486.         WinDdeInitiate(hwnd, "", "MAIL", &convContext);
  487.         break;
  488.  
  489.     case WM_DDE_INITIATE:
  490.         pddeInit = PVOIDFROMMP(mp2);
  491.         if (HWNDFROMMP(mp1) == hwnd)
  492.             break;
  493.         if ((strcmp("PMNOS", pddeInit->pszAppName) == 0) &&
  494.             (strlen(pddeInit->pszTopic) == 0 ||
  495.             (strcmp("MAIL", pddeInit->pszTopic) == 0)))
  496.             {
  497.             pNode1 = malloc(sizeof(NODE));
  498.             if(!pNode1)
  499.                 break;
  500.             memset(pNode1, '\0', sizeof(NODE));
  501.             pNode1->hwndClient = HWNDFROMMP(mp1);
  502.             WinCreateWindow(hwnd,
  503.                             "DDE",
  504.                             "",
  505.                             0L,
  506.                             0, 0, 0, 0,
  507.                             hwnd,
  508.                             HWND_TOP,
  509.                             1,
  510.                             pNode1,
  511.                             NULL);
  512.             }
  513.         break;
  514.  
  515.     case UM_BMAIL:
  516.         err = WinGetLastError(hab);
  517.         rc = WinBroadcastMsg(hwndMainFrame, UM_MAIL, mp1,
  518.                 0L, BMSG_DESCENDANTS | BMSG_SEND);
  519.         free(mp1);
  520.     break;
  521.  
  522.     case UM_SESSION:
  523.         errid = WinGetLastError(hab);
  524.         rc = ERRORIDERROR(errid);
  525.         sp = PVOIDFROMMP(mp1);
  526.         if (!sp->name)
  527.             sp->name = strdup("Unknown peer");
  528.         pszName = malloc(strlen(sp->name) + strlen(szClientClass) + 4);
  529.         strcpy(pszName, szClientClass);
  530.         strcat(pszName, " - ");
  531.         strcat(pszName, sp->name);
  532.         if (sp != NULLSESSION)
  533.             {
  534.             sp->hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  535.                             0,
  536.                             &flFrameFlags,
  537.                             szClientClass,
  538.                             pszName,
  539.                             0,
  540.                             (HMODULE)NULL,
  541.                             ID_RESOURCE,
  542.                             &sp->hwndSession);
  543.             if (!sp->hwndFrame)
  544.                 {
  545.                 prtError(hab, hwnd);
  546.                 break;
  547.                 }
  548.             pObject = (POBJECT)WinQueryWindowULong(sp->hwndSession, 0);
  549.             WinSetWindowPos(sp->hwndFrame,
  550.                     HWND_TOP,
  551.                     rectl.xLeft,
  552.                     rectl.yBottom,
  553.                     rectl.xRight,
  554.                     rectl.yTop,
  555.                     SWP_SHOW | SWP_SIZE);
  556.             WinQueryWindowPos(sp->hwndSession, &swp);
  557.             cy = 0;
  558.             if (sp->split)
  559.                 cy = (ULONG)((double)fat.lMaxBaselineExt * 1.25);
  560.             pObject->hwndMle = WinCreateWindow(sp->hwndSession,
  561.                                             WC_MLE,
  562.                                             "",
  563.                                             WS_VISIBLE | MLS_VSCROLL |MLS_WORDWRAP,
  564.                                             0, cy, swp.cx, swp.cy - cy,
  565.                                             sp->hwndSession,
  566.                                             HWND_TOP,
  567.                                             1,
  568.                                             NULL,
  569.                                             NULL);
  570.             if (!pObject->hwndMle)
  571.                 {
  572.                 prtError(hab, hwnd);
  573.                 break;
  574.                 }
  575.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETFONT, MPFROMP(&fat), 0L);
  576.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETTABSTOP, MPFROMSHORT(8 *(short)fat.lAveCharWidth), 0L);
  577.             if (rc == 0)
  578.                 prtError(hab, hwnd);
  579.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETBACKCOLOR, MPFROMLONG(CLR_BACKGROUND), 0L);
  580.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETTEXTLIMIT, MPFROMLONG(-1), 0L);
  581.             if (sp->split)
  582.                 {
  583.                 pObject->hwndEntry = WinCreateWindow(sp->hwndSession,
  584.                                                     WC_ENTRYFIELD,
  585.                                                     "",
  586.                                                     WS_VISIBLE | ES_AUTOSCROLL,
  587.                                                     0,0, swp.cx, cy,
  588.                                                     sp->hwndSession,
  589.                                                     HWND_TOP,
  590.                                                     12,
  591.                                                     NULL,
  592.                                                     NULL);
  593.  
  594.                 rc = (int)WinSendMsg(pObject->hwndEntry, EM_SETTEXTLIMIT, MPFROMSHORT(256), 0L);
  595.                 rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETREADONLY, MPFROMSHORT(1), 0L);
  596.                 pfnEntry = WinSubclassWindow(pObject->hwndEntry, NewEntryWndProc);
  597.                 rc = WinSetFocus(HWND_DESKTOP, pObject->hwndEntry);
  598.                 }
  599.             else
  600.                 rc = WinSetFocus(HWND_DESKTOP, pObject->hwndMle);
  601.             if (rc == 0)
  602.                 prtError(hab, hwnd);
  603.             errid = WinGetLastError(hab);
  604.             rc = ERRORIDERROR(errid);
  605.             pfnMle = WinSubclassWindow(pObject->hwndMle, NewMleWndProc);
  606.             pObject->pSession = sp;
  607.             free(pszName);
  608.             sp->screen = callocw(1,sizeof(struct screen));
  609.             sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  610.             sp->flowmode = 0;    /* Off by default */
  611.             sp->row = MOREROWS;
  612.             sp->morewait = 0;
  613.             pObject->display = sp->display = newproc("display", 4096, display, 1, pObject->pSession, NULL, 0);
  614.             }
  615.         if (mp2)
  616.             DosPostEventSem(Curproc->sem);
  617.         break;
  618.  
  619.     case UM_ERROR:
  620.         pszText = malloc(64);
  621.         pException = (EXCEPTIONREPORTRECORD *)mp2;
  622.         tmpProc = (struct proc *)mp1;
  623.         sprintf(pszText, "Exception occurred at %8x in %s", pException->ExceptionAddress, ((struct proc *)mp1)->name);
  624.         WinMessageBox(HWND_DESKTOP, hwnd, pszText, "PMNOS Error", 0, MB_ICONEXCLAMATION | MB_OK);
  625.         free(pszText);
  626.         free(mp1);
  627.         free(mp2);
  628.         break;
  629.  
  630.     case UM_SETFONT:
  631.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  632.         if (pObject->hwndMle)
  633.             WinSendMsg(pObject->hwndMle, MLM_SETFONT, mp1, mp2);
  634.         break;
  635.     case UM_TRACE:
  636.         sp = PVOIDFROMMP(mp1);
  637.         pszName = malloc(strlen(sp->name) + strlen(szClientClass) + 4);
  638.         strcpy(pszName, szClientClass);
  639.         strcat(pszName, " - ");
  640.         strcat(pszName, sp->name);
  641.         if (sp != NULLSESSION)
  642.             {
  643.             sp->type = TRACESESSION;
  644.             sp->hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  645.                             0,
  646.                             &flFrameFlags,
  647.                             szClientClass,
  648.                             pszName,
  649.                             0,
  650.                             (HMODULE)NULL,
  651.                             ID_RESOURCE,
  652.                             &sp->hwndSession);
  653.             if (!sp->hwndFrame)
  654.                 {
  655.                 prtError(hab, hwnd);
  656.                 break;
  657.                 }
  658.             pObject = (POBJECT)WinQueryWindowULong(sp->hwndSession, 0);
  659.             WinSetWindowPos(sp->hwndFrame,
  660.                     HWND_TOP,
  661.                     rectl.xLeft,
  662.                     rectl.yBottom,
  663.                     rectl.xRight,
  664.                     rectl.yTop,
  665.                     SWP_SHOW | SWP_SIZE);
  666.             WinQueryWindowPos(sp->hwndSession, &swp);
  667.             pObject->hwndMle = WinCreateWindow(sp->hwndSession,
  668.                                             WC_MLE,
  669.                                             "",
  670.                                             MLS_VSCROLL,
  671.                                             0, 0, swp.cx, swp.cy,
  672.                                             sp->hwndSession,
  673.                                             HWND_TOP,
  674.                                             1,
  675.                                             NULL,
  676.                                             NULL);
  677.             if (!pObject->hwndMle)
  678.                 {
  679.                 prtError(hab, hwnd);
  680.                 break;
  681.                 }
  682.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETFONT, MPFROMP(&fat), 0L);
  683.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETTABSTOP, MPFROMSHORT(8 *(short)fat.lAveCharWidth), 0L);
  684.             if (rc == 0)
  685.                 prtError(hab, hwnd);
  686.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETBACKCOLOR, MPFROMLONG(CLR_BACKGROUND), 0L);
  687.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETTEXTLIMIT, MPFROMLONG(-1), 0L);
  688.             pObject = (POBJECT)WinQueryWindowULong(sp->hwndSession, 0);
  689.             pObject->pSession = sp;
  690.             WinShowWindow(pObject->hwndMle, TRUE);
  691.             rc = WinSetFocus(HWND_DESKTOP, pObject->hwndMle);
  692.             if (rc == 0)
  693.                 prtError(hab, hwnd);
  694.             errid = WinGetLastError(hab);
  695.             rc = ERRORIDERROR(errid);
  696.             free(pszName);
  697.             DosPostEventSem(Curproc->sem);
  698.             }
  699.         break;
  700.  
  701.     case WM_SIZE:
  702.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  703.         pObject->cxClient = SHORT1FROMMP(mp2);
  704.         pObject->cyClient = SHORT2FROMMP(mp2);
  705.         if (pObject->hwndEntry)
  706.             {
  707.             WinSetWindowPos(pObject->hwndEntry,
  708.                     HWND_TOP,
  709.                     0, 0,
  710.                     pObject->cxClient, fat.lMaxBaselineExt,
  711.                     SWP_SIZE);
  712.             WinSetWindowPos(pObject->hwndMle,
  713.                     HWND_TOP,
  714.                     0, fat.lMaxBaselineExt,
  715.                     pObject->cxClient, pObject->cyClient - fat.lMaxBaselineExt,
  716.                     SWP_SIZE);
  717.             }
  718.          else
  719.             WinSetWindowPos(pObject->hwndMle,
  720.                     HWND_TOP,
  721.                     0, 0,
  722.                     pObject->cxClient, pObject->cyClient,
  723.                     SWP_SIZE);
  724.         break;
  725.  
  726.     case UM_REFRESH:
  727.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  728.         if (!pObject->hwndMle)
  729.             break;
  730.         if (mp1)
  731.             WinSendMsg(pObject->hwndMle, MLM_ENABLEREFRESH, 0L, 0L);
  732.         else
  733.             WinSendMsg(pObject->hwndMle, MLM_DISABLEREFRESH, 0L, 0L);
  734.         errid = WinGetLastError(hab);
  735.         rc = ERRORIDERROR(errid);
  736.         break;
  737.  
  738.     case UM_BS:
  739.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  740.         mrResult = WinSendMsg(pObject->hwndMle, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  741.         ulCharCnt = LONGFROMMR(mrResult);
  742.         WinSendMsg(pObject->hwndMle, MLM_DELETE, MPFROMLONG(ulCharCnt), MPFROMLONG(1L));
  743.         break;
  744.  
  745.  
  746.     case UM_ERASELINE:
  747.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  748.         mrResult = WinSendMsg(pObject->hwndMle, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  749.         ulCharCnt = LONGFROMMR(mrResult);
  750.         mrResult = WinSendMsg(pObject->hwndMle, MLM_CHARFROMLINE, MPFROMLONG(-1L), MPFROMLONG(0L));
  751.         ulCharCnt -= LONGFROMMR(mrResult);
  752.         WinSendMsg(pObject->hwndMle, MLM_DELETE, (MPARAM)mrResult, MPFROMLONG(ulCharCnt + 1));
  753.         break;
  754.  
  755.     case MLM_INSERT:
  756.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  757.         mrResult = WinSendMsg(pObject->hwndMle, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  758.         ulCharCnt = LONGFROMMR(mrResult);
  759.         WinSendMsg(pObject->hwndMle, MLM_SETSEL, MPFROMLONG(ulCharCnt), MPFROMLONG(ulCharCnt));
  760.         if (mp2)
  761.             {
  762.             WinSendMsg(pObject->hwndMle, msg, mp1, 0L);
  763.             free(PVOIDFROMMP(mp1));
  764.             }
  765.         else
  766.             WinSendMsg(pObject->hwndMle, msg, mp1, mp2);
  767.         break;
  768.  
  769.     case UM_INSERT:
  770.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  771.         if (!pObject->pSession->split)
  772.             break;
  773.         mrResult = WinSendMsg(pObject->hwndMle, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  774.         ulCharCnt = LONGFROMMR(mrResult);
  775.         WinSendMsg(pObject->hwndMle, MLM_SETSEL, MPFROMLONG(ulCharCnt), MPFROMLONG(ulCharCnt));
  776.         if (mp2)
  777.             {
  778.             WinSendMsg(pObject->hwndMle, MLM_INSERT, mp1, 0L);
  779.             free(PVOIDFROMMP(mp1));
  780.             }
  781.         else
  782.             WinSendMsg(pObject->hwndMle, MLM_INSERT, mp1, mp2);
  783.         break;
  784.  
  785.     case UM_DESTROY:
  786.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  787.         rc = WinDestroyWindow(pObject->pSession->hwndFrame);
  788.         if (rc == 0)
  789.             prtError(hab, hwnd);
  790.         break;
  791.  
  792.  
  793.     case WM_DESTROY:
  794.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  795.         free(pObject);
  796.         break;
  797.  
  798.     case WM_CLOSE:
  799.         if (!main_exit)
  800.             {
  801.             Keyboard.rp = Keyboard.wp = Keyboard.buf;
  802.             strcpy(Keyboard.buf, "exit\n");
  803.             Keyboard.cnt = 5;
  804.             psignal(&Keyboard, 0);
  805.             }
  806.         else
  807.             WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  808.         errid = WinGetLastError(hab);
  809.         rc = ERRORIDERROR(errid);
  810.         break;
  811.  
  812.     case WM_CONTROL:
  813.         pObject = (POBJECT)WinQueryWindowULong(hwnd, 0);
  814.         switch (SHORT2FROMMP(mp1))
  815.             {
  816.             case MLN_CHANGE:
  817.                 if (SHORT1FROMMP(mp1) == 1 || SHORT1FROMMP(mp1) == 12)
  818.                     WinPostMsg(WinQueryCapture(HWND_DESKTOP), WM_MOUSEMOVE, MPFROM2SHORT(100,100), 0L);
  819.                 break;
  820.  
  821.             case MLN_OVERFLOW:
  822.             case MLN_TEXTOVERFLOW:
  823.             case MLN_MEMERROR:
  824.                 if(SHORT1FROMMP(mp1) != 1)     /* not our mle entry field */
  825.                     break;
  826.                 WinSendMsg(pObject->hwndMle, MLM_DISABLEREFRESH, 0L, 0L);
  827.                 i = (int)WinSendMsg(pObject->hwndMle, MLM_QUERYLINECOUNT, 0L, 0L);
  828.                 i /= 2;
  829.                 i = (int)WinSendMsg(pObject->hwndMle, MLM_CHARFROMLINE, MPFROMLONG(i), 0L);
  830.                 WinSendMsg(pObject->hwndMle, MLM_SETSEL, 0L, MPFROMLONG(i));
  831.                 WinSendMsg(pObject->hwndMle, MLM_CLEAR, 0L, 0L);
  832.                 mrResult = WinSendMsg(pObject->hwndMle, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  833.                 ulCharCnt = LONGFROMMR(mrResult);
  834.                 WinSendMsg(pObject->hwndMle, MLM_SETSEL, MPFROMLONG(ulCharCnt), MPFROMLONG(ulCharCnt));
  835.                 WinSendMsg(pObject->hwndMle, MLM_ENABLEREFRESH, 0L, 0L);
  836.                 break;
  837.             default:
  838.                 return(MRFROMSHORT(TRUE));
  839.             }
  840.         break;
  841.  
  842.     case WM_COMMAND:
  843.         switch (SHORT1FROMMP(mp1))
  844.         {
  845.         case IDM_FONT:
  846.             pFont = malloc(sizeof(FONTDLG));
  847.             pFamily = malloc(64);
  848.             memset(pFont, '\0', sizeof(FONTDLG));
  849.             pFont->cbSize = sizeof(FONTDLG);
  850.             pFont->hpsScreen = WinGetPS(hwnd);
  851.             pFont->pszFamilyname = pFamily;
  852.             strcpy(pFamily, "Courier");
  853.             pFont->usFamilyBufLen = strlen(pFamily);
  854.             pFont->pszTitle = "PM NOS Setup";
  855.             pFont->fl = FNTS_CENTER | FNTS_INITFROMFATTRS;
  856.             pFont->clrFore = CLR_BLACK;
  857.             pFont->clrBack = CLR_WHITE;
  858.             pFont->usWeight = FWEIGHT_NORMAL;
  859.             pFont->usWidth = FWIDTH_NORMAL;
  860.             pFont->fxPointSize = MAKEFIXED(8,0);
  861.             memcpy(&pFont->fAttrs, &fat, sizeof(FATTRS));
  862.             hDlg = WinFontDlg(HWND_DESKTOP, hwnd, pFont);
  863.             WinReleasePS(pFont->hpsScreen);
  864.             if (hDlg && (pFont->lReturn == DID_OK))
  865.                 {
  866.                 memcpy(&fat, &pFont->fAttrs, sizeof(FATTRS));
  867.                 rc = WinBroadcastMsg(hwndMainFrame, UM_SETFONT, MPFROMP(&fat),
  868.                     0L, BMSG_DESCENDANTS | BMSG_SEND);
  869.                 }
  870.             free(pFont);
  871.             free(pFamily);
  872.             break;
  873.  
  874.         case IDM_ABOUT:
  875.             WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc,
  876.                   (HMODULE)NULL, IDD_ABOUT, NULL);
  877.             break;
  878.         }
  879.         break;
  880.  
  881.     default:
  882.         return WinDefWindowProc (hwnd, msg, mp1, mp2);
  883.     }
  884.     return (MRFROMSHORT(0));
  885. }
  886.  
  887.  
  888. MRESULT EXPENTRY AboutDlgProc(HWND hDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
  889. /*
  890.     About... dialog procedure
  891. */
  892. {
  893.     switch(msg)
  894.     {
  895.     case WM_COMMAND:
  896.         switch(SHORT1FROMMP(mp1))
  897.         {
  898.         case DID_OK:
  899.         case DID_CANCEL:
  900.             WinDismissDlg(hDlg, TRUE);
  901.             break;
  902.  
  903.         default:
  904.             break;
  905.         }
  906.         break;
  907.     default:
  908.         return WinDefDlgProc(hDlg, msg, mp1, mp2);
  909.  
  910.     }
  911.     return MRFROMSHORT(FALSE);
  912. }
  913.  
  914. MRESULT EXPENTRY NewMleWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  915. {
  916. USHORT fsKeyFlags, usChar, usVKey;
  917. UCHAR uchRepeat;
  918. HWND hwndParent;
  919. POBJECT pObject;
  920. MRESULT mrResult;
  921. ULONG ulCharCnt;
  922.  
  923.     hwndParent = WinQueryWindow(hwnd, QW_PARENT);
  924.     pObject = (POBJECT)WinQueryWindowULong(hwndParent, 0);
  925.  
  926.     switch(msg)
  927.         {
  928.         case WM_SETFOCUS:
  929.             if (SHORT1FROMMP(mp2))
  930.                 {
  931.                 Lastcurr = Current;
  932.                 Current = pObject->pSession;
  933.                 if(pObject->hwndEntry)
  934.                     {
  935.                     WinAlarm(HWND_DESKTOP, WA_WARNING);
  936.                     WinPostMsg(pObject->hwndEntry, UM_SETFOCUS, MPFROMHWND(pObject->hwndEntry), MPFROMSHORT(TRUE));
  937.                     }
  938.                 else
  939.                     {
  940.                     mrResult = WinSendMsg(hwnd, MLM_QUERYTEXTLENGTH, MPFROMLONG(0L), MPFROMLONG(0L));
  941.                     ulCharCnt = LONGFROMMR(mrResult);
  942.                     WinSendMsg(hwnd, MLM_SETSEL, MPFROMLONG(ulCharCnt + 300), MPFROMLONG(ulCharCnt + 300));
  943.                     WinPostMsg(hwnd, WM_MOUSEMOVE, MPFROM2SHORT(20,20), 0L);
  944.                     WinPostMsg(hwnd, WM_BUTTON1DOWN, MPFROM2SHORT(1,100), 0L);
  945.                     WinPostMsg(hwnd, WM_BUTTON1UP, MPFROM2SHORT(1,100), 0L);
  946.                     }
  947.                 }
  948.             return((pfnMle)(hwnd, msg, mp1, mp2));
  949.  
  950.         case WM_CHAR:
  951.             if (pObject->hwndEntry)
  952.                 return(MPFROMSHORT(TRUE));
  953.             fsKeyFlags = (USHORT)SHORT1FROMMP(mp1);
  954.             uchRepeat = (UCHAR)CHAR3FROMMP(mp1);
  955.             Keyboard.uchScanCode = (UCHAR)CHAR4FROMMP(mp1);
  956.             usChar = (USHORT)SHORT1FROMMP(mp2);
  957.             usVKey = (USHORT)SHORT2FROMMP(mp2);
  958.             if (!(fsKeyFlags & KC_KEYUP))
  959.                 if ((fsKeyFlags & KC_CHAR))
  960.                     {
  961.                     while (uchRepeat--)
  962.                         {
  963.                         *Keyboard.wp++ = usChar;
  964.                         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  965.                             Keyboard.wp = Keyboard.buf;
  966.                         Keyboard.cnt++;
  967.                         psignal(&Keyboard,0);
  968.                         }
  969.                     if(!Current->ttystate.echo)
  970.                         return(MRFROMSHORT(TRUE));
  971.                     }
  972.                 else
  973.                    if (fsKeyFlags & KC_CTRL && (usChar & 0xff))
  974.                         {
  975.                         usChar &= 0xdf; /* make uppercase */
  976.                         *Keyboard.wp++ = usChar - 0x40;
  977.                         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  978.                             Keyboard.wp = Keyboard.buf;
  979.                         Keyboard.cnt++;
  980.                         psignal(&Keyboard,0);
  981.                         }
  982.                    else
  983.                         if (fsKeyFlags & KC_VIRTUALKEY && ((usChar & 0x1b) == 0x1b))
  984.                           {
  985.                           *Keyboard.wp++ = 0x1b;
  986.                           if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  987.                               Keyboard.wp = Keyboard.buf;
  988.                           Keyboard.cnt++;
  989.                           psignal(&Keyboard,0);
  990.                           }
  991.  
  992.             return((MRESULT)(pfnMle)(hwnd, msg, mp1, mp2));
  993.  
  994.         default:
  995.             return((pfnMle)(hwnd, msg, mp1, mp2));
  996.         }
  997.     return((MRESULT)FALSE);
  998. }
  999.  
  1000. MRESULT EXPENTRY NewEntryWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1001. {
  1002. USHORT fsKeyFlags, usChar, usVKey;
  1003. UCHAR uchRepeat;
  1004. HWND hwndParent;
  1005. POBJECT pObject;
  1006. char *pTmp;
  1007.  
  1008.     hwndParent = WinQueryWindow(hwnd, QW_PARENT);
  1009.     pObject = (POBJECT)WinQueryWindowULong(hwndParent, 0);
  1010.     switch(msg)
  1011.         {
  1012.  
  1013.         case UM_SETFOCUS:
  1014.             WinSetFocus(hwnd, TRUE);
  1015.             WinPostMsg(hwnd, WM_MOUSEMOVE, MPFROM2SHORT(20,20), 0L);
  1016.             WinPostMsg(hwnd, WM_BUTTON1DOWN, MPFROM2SHORT(1,100), 0L);
  1017.             WinPostMsg(hwnd, WM_BUTTON1UP, MPFROM2SHORT(1,100), 0L);
  1018.             break;
  1019.  
  1020.         case WM_CHAR:
  1021.             fsKeyFlags = (USHORT)SHORT1FROMMP(mp1);
  1022.             uchRepeat = (UCHAR)CHAR3FROMMP(mp1);
  1023.             Keyboard.uchScanCode = (UCHAR)CHAR4FROMMP(mp1);
  1024.             usChar = (USHORT)SHORT1FROMMP(mp2);
  1025.             usVKey = (USHORT)SHORT2FROMMP(mp2);
  1026.             if (!(fsKeyFlags & KC_KEYUP))
  1027.                 if ((fsKeyFlags & KC_CHAR) )
  1028.                     {
  1029.                     while (uchRepeat--)
  1030.                         {
  1031.                         *Keyboard.wp++ = usChar;
  1032.                         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  1033.                             Keyboard.wp = Keyboard.buf;
  1034.                         Keyboard.cnt++;
  1035.                         psignal(&Keyboard,0);
  1036.                         }
  1037.                     if(usChar == 0x0D)
  1038.                         {
  1039.                         pTmp = malloc(256);
  1040.                         WinQueryWindowText(hwnd, 256, pTmp);
  1041.                         strcat(pTmp, "\n\r");
  1042.                         WinPostMsg(pObject->pSession->hwndSession, MLM_INSERT, MPFROMP(pTmp), MPFROMLONG(256L));
  1043.                         WinSetWindowText(hwnd, "");
  1044.                         return(MPFROMSHORT(TRUE));
  1045.                         }
  1046.                     if(!Current->ttystate.echo)
  1047.                         return(MRFROMSHORT(TRUE));
  1048.                     }
  1049.                 else
  1050.                    if (fsKeyFlags & KC_CTRL && (usChar & 0xff))
  1051.                         {
  1052.                         usChar &= 0xdf; /* make uppercase */
  1053.                         *Keyboard.wp++ = usChar - 0x40;
  1054.                         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  1055.                             Keyboard.wp = Keyboard.buf;
  1056.                         Keyboard.cnt++;
  1057.                         psignal(&Keyboard,0);
  1058.                         }
  1059.                    else
  1060.                         if (fsKeyFlags & KC_VIRTUALKEY && ((usChar & 0x1b) == 0x1b))
  1061.                           {
  1062.                           *Keyboard.wp++ = 0x1b;
  1063.                           if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  1064.                               Keyboard.wp = Keyboard.buf;
  1065.                           Keyboard.cnt++;
  1066.                           psignal(&Keyboard,0);
  1067.                           }
  1068.  
  1069.             return((MRESULT)(pfnEntry)(hwnd, msg, mp1, mp2));
  1070.  
  1071.         default:
  1072.             return((pfnEntry)(hwnd, msg, mp1, mp2));
  1073.         }
  1074.     return((MRESULT)FALSE);
  1075. }
  1076.  
  1077. void newTrace(struct session *sp)
  1078. {
  1079. ULONG    ulPostCt;
  1080.  
  1081.     DosEnterCritSec();
  1082.     WinPostMsg(Command->hwndSession, UM_TRACE, MPFROMP(sp), MPFROMLONG(1L));
  1083.     DosResetEventSem(Curproc->sem, &ulPostCt);
  1084.     DosExitCritSec();
  1085.     DosWaitEventSem(Curproc->sem, SEM_INDEFINITE_WAIT);
  1086. }
  1087.  
  1088. void freeTrace(struct session *sp)
  1089. {
  1090.     WinPostMsg(sp->hwndSession, UM_DESTROY, MPFROMLONG(0L), MPFROMLONG(0L));
  1091.     errid = WinGetLastError(hab);
  1092.     rc = ERRORIDERROR(errid);
  1093.     WinPostMsg(sp->hwndFrame, WM_DESTROY, MPFROMLONG(0L), MPFROMLONG(0L));
  1094. }
  1095.  
  1096. void
  1097. newscreen(struct session *sp)
  1098. {
  1099. PSZ    pszName;
  1100. POBJECT pObject;
  1101. PTIB    pptib;
  1102. PPIB    pppib;
  1103. ULONG    ulPostCt;
  1104. SWP swp;
  1105. PERRINFO pErr;
  1106. int rc;
  1107.  
  1108.     DosGetInfoBlocks(&pptib, &pppib);
  1109.     if (sp != NULLSESSION)
  1110.         if (pptib->tib_ptib2->tib2_ultid != 1)
  1111.             {
  1112.             DosEnterCritSec();
  1113.             WinPostMsg(Command->hwndSession, UM_SESSION, MPFROMP(sp), MPFROMLONG(1L));
  1114.             DosResetEventSem(Curproc->sem, &ulPostCt);
  1115.             DosExitCritSec();
  1116.             DosWaitEventSem(Curproc->sem, SEM_INDEFINITE_WAIT);
  1117.             }
  1118.         else
  1119.             {
  1120.             pszName = malloc(strlen(sp->name) + strlen(szClientClass) + 4);
  1121.             strcpy(pszName, szClientClass);
  1122.             strcat(pszName, " - ");
  1123.             strcat(pszName, sp->name);
  1124.             sp->hwndFrame = hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  1125.                              0L,
  1126.                             &flFrameFlags,
  1127.                             szClientClass,
  1128.                             pszName,
  1129.                             0L,
  1130.                             (HMODULE)NULL,
  1131.                             ID_RESOURCE,
  1132.                             &sp->hwndSession) ;
  1133.             hwndCmd = sp->hwndSession;
  1134.             if (!hwndFrame)
  1135.                 prtError(hab, sp->hwndFrame);
  1136.  
  1137.             pObject = (POBJECT)WinQueryWindowULong(sp->hwndSession, 0);
  1138.             WinQueryWindowPos(sp->hwndSession, &swp);
  1139.             pObject->hwndMle = WinCreateWindow(sp->hwndSession,
  1140.                                             WC_MLE,
  1141.                                             "",
  1142.                                             WS_VISIBLE | MLS_VSCROLL |MLS_WORDWRAP,
  1143.                                             0, 0, swp.cx, swp.cy,
  1144.                                             sp->hwndSession,
  1145.                                             HWND_TOP,
  1146.                                             1,
  1147.                                             NULL,
  1148.                                             NULL);
  1149.             if (!pObject->hwndMle)
  1150.                 {
  1151.                 prtError(hab, sp->hwndFrame);
  1152.                 return;
  1153.                 }
  1154.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETFONT, MPFROMP(&fat), 0L);
  1155.             rc = (int)WinSendMsg(pObject->hwndMle, MLM_SETTABSTOP, MPFROMSHORT(8 *(short)fat.lAveCharWidth), 0L);
  1156.             if (rc == 0)
  1157.                 prtError(hab, sp->hwndFrame);
  1158.             WinSendMsg(pObject->hwndMle, MLM_SETBACKCOLOR, MPFROMLONG(CLR_BACKGROUND), 0L);
  1159.             WinSendMsg(pObject->hwndMle, MLM_SETTEXTLIMIT, MPFROMLONG(-1), 0L);
  1160.             if (rc == 0)
  1161.                 prtError(hab, sp->hwndFrame);
  1162.             rc = WinSetFocus(HWND_DESKTOP, pObject->hwndMle);
  1163.             pfnMle = WinSubclassWindow(pObject->hwndMle, NewMleWndProc);
  1164.             if (rc == 0)
  1165.                 prtError(hab, sp->hwndFrame);
  1166.             free(pszName);
  1167.             sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  1168.             pObject->pSession = sp;
  1169.             pObject->display = sp->display = newproc("display", 4096, display, 1, pObject->pSession, NULL, 0);
  1170.             }
  1171. }
  1172.  
  1173. void
  1174. freescreen(struct session *sp)
  1175. {
  1176.     if(sp == NULLSESSION || sp->screen == NULLSCREEN)
  1177.         return;
  1178.     if(sp->screen->save != NULLCHAR)
  1179.         free(sp->screen->save);
  1180.     free((char *)sp->screen);
  1181.     WinPostMsg(sp->hwndSession, UM_DESTROY, MPFROMLONG(0L), MPFROMLONG(0L));
  1182.     errid = WinGetLastError(hab);
  1183.     rc = ERRORIDERROR(errid);
  1184.     WinPostMsg(sp->hwndFrame, WM_DESTROY, MPFROMLONG(0L), MPFROMLONG(0L));
  1185.     errid = WinGetLastError(hab);
  1186.     rc = ERRORIDERROR(errid);
  1187.     killproc(sp->display);
  1188. }
  1189.  
  1190. int kbread()
  1191. {
  1192. int c;
  1193.     if((c = kbchar()) == 0){
  1194.         switch(Keyboard.uchScanCode){
  1195.         case 3:        /* NULL (bizzare!) */
  1196.             c = 0;
  1197.             break;
  1198.         case 61:    /* F-3 key (used as line-repeat) */
  1199.             c = 2;
  1200.             break;
  1201.         case 68:    /* F-10 key (used as command-mode escape) */
  1202.             c = -2;
  1203.             break;
  1204.         case 83:    /* DEL key */
  1205.             c = 0x7f;
  1206.             break;
  1207.         default:    /* Dunno what it is */
  1208.             c = -1;
  1209.         }
  1210.     }
  1211.     return c;
  1212. }
  1213.  
  1214. static int
  1215. kbchar()
  1216. {
  1217. char i_state;
  1218. char c;
  1219.  
  1220.     /*i_state = dirps();*/
  1221.     while(Keyboard.cnt == 0)
  1222.         pwait(&Keyboard);
  1223.     Keyboard.cnt--;
  1224.     /*restore(i_state);*/
  1225.     c = *Keyboard.rp++;
  1226.     if(Keyboard.rp == &Keyboard.buf[KBSIZE])
  1227.         Keyboard.rp = Keyboard.buf;
  1228.     return uchar(c);
  1229. }
  1230.  
  1231. void MailNotify(char *pszUser)
  1232. {
  1233. ERRORID err;
  1234. int rc;
  1235. char *pszItem;
  1236.     pszItem = strdup(pszUser);
  1237.     WinPostMsg(Command->hwndSession, UM_BMAIL, MPFROMP(pszItem), 0L);
  1238.     return;
  1239. }
  1240. PDDESTRUCT MakeDDEObject(PSZ pszItemName, USHORT usStatus, USHORT usFormat,
  1241.             PVOID pData, USHORT usDataLen)
  1242. {
  1243. PDDESTRUCT pddes;
  1244. ULONG        ulItemLength;
  1245. PULONG        pulSharedObj;
  1246.  
  1247.     if (pszItemName)
  1248.         ulItemLength = strlen(pszItemName) + 1;
  1249.     else
  1250.         ulItemLength = 0L;
  1251.     if (!DosAllocSharedMem((PVOID)&pulSharedObj,
  1252.                 NULL,
  1253.                 sizeof(DDESTRUCT) + ulItemLength + usDataLen,
  1254.                 PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE |OBJ_GETTABLE))
  1255.         {
  1256.         pddes = (PDDESTRUCT)pulSharedObj;
  1257.         memset(pddes, '\0', sizeof(DDESTRUCT));
  1258.         pddes->cbData = usDataLen + sizeof(DDESTRUCT) + ulItemLength;
  1259.         pddes->fsStatus = usStatus;
  1260.         pddes->usFormat = usFormat;
  1261.         pddes->offszItemName = sizeof(DDESTRUCT);
  1262.         if (usDataLen && pData)
  1263.             pddes->offabData = sizeof(DDESTRUCT) + ulItemLength;
  1264.         if (pszItemName)
  1265.             strcpy(DDES_PSZITEMNAME(pddes), pszItemName);
  1266.         if (pData)
  1267.             memcpy(DDES_PABDATA(pddes), pData, usDataLen);
  1268.         return(pddes);
  1269.         }
  1270.     return((PDDESTRUCT)NULL);
  1271. }
  1272.  
  1273. int prtError(HAB hab, HWND hwnd)
  1274. {
  1275. char *pTmp, *pTmp1, *pTmp2;
  1276. PERRINFO pErr;
  1277. int i, rc, iOffset;
  1278.     i = 0;
  1279.     return(0);          /* remove for debug */
  1280.     pErr = WinGetErrorInfo(hab);
  1281.     if (!pErr)
  1282.         return(0);
  1283.     pTmp = malloc(256);
  1284.     if (!pTmp)
  1285.         {
  1286.         WinFreeErrorInfo(pErr);
  1287.         return(-1);
  1288.         }
  1289.     pTmp1 = malloc(256);
  1290.     if (!pTmp1)
  1291.         {
  1292.         free(pTmp);
  1293.         WinFreeErrorInfo(pErr);
  1294.         return(-1);
  1295.         }
  1296.     pTmp2 = malloc(256);
  1297.     if (!pTmp2)
  1298.         {
  1299.         free(pTmp);
  1300.         free(pTmp1);
  1301.         WinFreeErrorInfo(pErr);
  1302.         return(-1);
  1303.         }
  1304.     *pTmp1 = '\0';
  1305.     iOffset = (int)*((char *)pErr + (pErr->offaoffszMsg));
  1306.     for (i = 0; i < pErr->cDetailLevel; i++)
  1307.         {
  1308.         sprintf(pTmp2, (char *)((char *)pErr + iOffset + i), pErr + pErr->offBinaryData);
  1309.         strcat(pTmp1, pTmp2);
  1310.         strcat(pTmp1, "\n");
  1311.         }
  1312.     sprintf(pTmp, "Error - %x\n%s", pErr->idError, pTmp1);
  1313.     rc = WinMessageBox(HWND_DESKTOP, hwnd, pTmp, "PMNOS - Debug", 0, MB_ICONEXCLAMATION | MB_OKCANCEL);
  1314.     WinFreeErrorInfo(pErr);
  1315.     free(pTmp);
  1316.     free(pTmp1);
  1317.     free(pTmp2);
  1318.     return(rc);
  1319. }
  1320.  
  1321. static void display(int i, void *v1, void *v2)
  1322. {
  1323. BOOL    fNewLine;
  1324. PCHAR pachBuffer;
  1325. PCHAR pachBuffer1;
  1326. struct session *sp;
  1327. struct usock *up;
  1328. int icnt, c;
  1329. BOOL rc, fTerminate, fGathering;
  1330.     fTerminate = FALSE;
  1331.     sp = (struct session *)v1;
  1332.     up = itop((int)(sp->output));
  1333.     if (!up)
  1334.         return;    /* not properly initalized */
  1335.     pachBuffer1 = malloc(500);
  1336.     rc = WinPostMsg(sp->hwndSession, UM_REFRESH, MPFROMLONG(1L), MPFROMLONG(0L));
  1337.     while(!fTerminate)
  1338.         {
  1339.         fNewLine = FALSE;
  1340.         if(sp->morewait){
  1341.             pwait(&sp->row);
  1342.             if(sp != Current || sp->row <= 0){
  1343.                 /* Current changed value, or the user
  1344.                  * hasn't really hit a key
  1345.                  */
  1346.                 continue;
  1347.                 }
  1348.             /* Erase the prompt */
  1349.             do {
  1350.                 rc = WinPostMsg(sp->hwndSession, UM_ERASELINE, 0L, 0L);
  1351.                 if (rc == FALSE)
  1352.                     DosSleep(MSPTICK);
  1353.                 } while (rc == FALSE);
  1354.             }
  1355.         sp->morewait = 0;
  1356.         icnt = 0;
  1357.         pachBuffer = pachBuffer1;
  1358.         fGathering = TRUE;
  1359.         do
  1360.             {
  1361.             rc = WinPostMsg(sp->hwndSession, UM_REFRESH, 0L, 0L);
  1362.             if (rc == FALSE)
  1363.                 DosSleep(MSPTICK);
  1364.             } while (rc == FALSE);
  1365.         while(fGathering)
  1366.             {
  1367.             if (icnt == 499)
  1368.                 {
  1369.                 fGathering = FALSE;
  1370.                 break;
  1371.                 }
  1372.             c = rrecvchar(sp->output);
  1373.             up->noblock = TRUE;
  1374.  
  1375.             switch (c)
  1376.                 {
  1377.                 case EABORT:
  1378.                     fTerminate = TRUE;
  1379.                     free(pachBuffer1);
  1380.                     pachBuffer1 = NULL;
  1381.                     break;
  1382.  
  1383.                 case 0x07:
  1384.                     WinAlarm(HWND_DESKTOP, WA_NOTE);
  1385.                     break;
  1386.  
  1387.                 case 0x0d:
  1388.                     break;
  1389.  
  1390.                 case '\b':
  1391.                     if (icnt)
  1392.                         pachBuffer1[--icnt] = ' ';
  1393.                     break;
  1394.  
  1395.                 case 0x0a:
  1396.                     pachBuffer1[icnt++] = '\n';
  1397.                     break;
  1398.  
  1399.                 case '\t':
  1400.                     pachBuffer1[icnt++] = c;
  1401.                     break;
  1402.                 case -1:
  1403.                     fGathering = FALSE;
  1404.                     break;
  1405.  
  1406.                 default:
  1407.                     if (iscntrl(c))
  1408.                         break;
  1409.                     pachBuffer1[icnt++] = c;
  1410.                 }
  1411.             }
  1412.         if (fTerminate)
  1413.             return;
  1414.         if (icnt)
  1415.             {
  1416.             pachBuffer = malloc(icnt + 1);
  1417.             memcpy(pachBuffer, pachBuffer1, icnt);
  1418.             pachBuffer[icnt] = '\0';
  1419.             if(sp->record != NULLFILE)
  1420.                 fwrite(pachBuffer, icnt, 1, sp->record);
  1421.             do
  1422.                 {
  1423.                 rc = WinPostMsg(sp->hwndSession, MLM_INSERT, MPFROMP(pachBuffer), MPFROMLONG(icnt));
  1424.                 if (rc == FALSE)
  1425.                     DosSleep(MSPTICK);
  1426.                 } while (rc == FALSE);
  1427.             pachBuffer = NULL;
  1428.     /*        if(sp->flowmode && fNewLine && --sp->row <= 0){
  1429.                 do {
  1430.                     rc = WinPostMsg(sp->hwndSession, MLM_INSERT, MPFROMP("--More--"), 8L);
  1431.                     if (rc == FALSE)
  1432.                         DosSleep(MSPTICK);
  1433.                     sp->morewait = 1;
  1434.                     } while (rc == FALSE);
  1435.                 }*/
  1436.             }
  1437.         if (c == -1)
  1438.             {
  1439.             do
  1440.                 {
  1441.                 rc = WinPostMsg(sp->hwndSession, UM_REFRESH, MPFROMLONG(1L), MPFROMLONG(0L));
  1442.                 if (rc == FALSE)
  1443.                     DosSleep(MSPTICK);
  1444.                 } while (rc == FALSE);
  1445.             c = pwait(up);
  1446.             if (c == EABORT)
  1447.                 {
  1448.                 free(pachBuffer1);
  1449.                 return;
  1450.                 }
  1451.             }
  1452.         }
  1453. }
  1454.  
  1455.  
  1456.